package com.zz.check.util;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;

/**
 * jar包冲突检测工具类
 * @author zys
 *
 */
public class JarConflictDetectUtil {

	
	/**
	 * 检测并返回指定目录下所有冲突的jar包信息
	 * @param dirPath
	 * @return 
	 *         返回结果说明：     有冲突时返回HashMap<String, HashSet<String>>
	 *         			   key值为冲突的jar名称，以逗号隔开
	 *                     value值为冲突的class名称集合
	 *                   
	 */
	public static HashMap<String, HashSet<String>> getConflict(String dirPath){
		
		//最终返回结果
		HashMap<String, HashSet<String>> conflictMap=new HashMap<String, HashSet<String>>();
		//用来保存每个jar文件中的类名称
		HashMap<String, HashSet<String>> jarClassMap = new HashMap<String, HashSet<String>>();
		//存储所有jar中的类名称
		HashSet<String> allClassSet = new HashSet<String>();
		
		long classCount=0;
		File fileDir = new File(dirPath);
		File[] files=fileDir.listFiles();
		for(File file:files){
			//只处理jar文件
			if(file.toString().toUpperCase().endsWith(".JAR")){
				//获得一个jar文件中的类名称集合
				HashSet<String> classSet = JarUtil.getClassNames(file);
				jarClassMap.put(file.getName(), classSet);
				classCount+=classSet.size();
				allClassSet.addAll(classSet);//去重复
			}
		}
	
		//所有jar包类的数量与去重后的类数量不相等，则说明有重复类，继续下面的处理
		if(classCount!=allClassSet.size()){
			
			String jarNames=null;
			for(String className:allClassSet){
				//获取包含指定类名的jar名称
				jarNames = getJarNames(className,jarClassMap);
				//如果类名在多个jar文件中均存在则说明存在jar包冲突问题
				if(jarNames.contains(",")){
					//如果该冲突已经被存储
					if(conflictMap.containsKey(jarNames)){
						conflictMap.get(jarNames).add(className);
					}else{
						HashSet<String> hashSet=new HashSet<String>();
						hashSet.add(className);
						conflictMap.put(jarNames, hashSet);
					}
				}
			}
		}
		
		return conflictMap;
	}
	
	/**
	 * 获取包含指定类名的jar包名称
	 * @param className
	 * @return 多个jar文件时以逗号隔开
	 */
	private static String getJarNames(String className,HashMap<String, HashSet<String>> jarClassMap){
		String jarNames="";
		
		for(String jarName:jarClassMap.keySet()){
			if(jarClassMap.get(jarName).contains(className)){
				jarNames+=jarName+",";
			}
		}
		if(jarNames.endsWith(",")){
			jarNames=jarNames.substring(0,jarNames.length()-1);
		}
		return jarNames;
	}
	
	
	/**
	 * 从指定目录下获取包含指定类名的所有jar包名称
	 * @param dirPath jar包目录名称
	 * @param className 完整的类名称，例：com.zz.Test.class
	 * @return 多个jar以逗号隔开，无结果返回空字符串
	 */
	public static String getJarNames(String className,String dirPath){
		String jarNames="";
		HashSet<String> classSet=new HashSet<String>();;
		File fileDir = new File(dirPath);
		File[] files=fileDir.listFiles();
		for(File file:files){
			//只处理jar文件
			if(file.toString().toUpperCase().endsWith(".JAR")){
				//获得一个jar文件中的类名称集合
				classSet = JarUtil.getClassNames(file);
				if(classSet.contains(className)){
					jarNames+=file.getName()+",";
				}
			}
		}
		if(jarNames.endsWith(",")){
			jarNames=jarNames.substring(0,jarNames.length()-1);
		}
		return jarNames;
	}
	
}
